/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * NewJPanel2.java
 *
 * Created on Mar 5, 2011, 10:55:46 PM
 */

package com.bah.tract.client.ui;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.swing.DefaultCellEditor;
import javax.swing.JDialog;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import com.bah.tract.client.ErrorHandler;
import com.bah.tract.client.ui.ProjectComboModel.ProjectLabel;
import com.bah.tract.client.ui.TaskComboModel.TaskLabel;
import com.bah.tract.client.workstore.TaskProvider;
import com.bah.tract.client.workstore.TaskProviderFactory;
import com.bah.tract.service.Project;
import com.bah.tract.service.ProjectList;
import com.bah.tract.service.ProjectService;
import com.bah.tract.service.Task;
import com.bah.tract.service.TractServiceException_Exception;
import com.bah.tract.service.UpdatedWork;
import com.bah.tract.service.Work;
import com.bah.tract.service.WorkService;
import com.bah.tract.service.WorkStore;
import com.toedter.calendar.JDateChooser;

@Singleton
public class TaskEditDialog extends JDialog {
	private final TOLPropertiesDialog mTolPropertiesDialog;

	/**
	 * 
	 * @author 524506
	 */
	public class TaskEditPanel extends javax.swing.JPanel {

		/**
	 * 
	 */
		private static final long serialVersionUID = -5236000241438348080L;

		/** Creates new form NewJPanel2 */
		public TaskEditPanel() {
			initComponents();
		}

		/**
		 * This method is called from within the constructor to initialize the
		 * form. WARNING: Do NOT modify this code. The content of this method is
		 * always regenerated by the Form Editor.
		 */
		// <editor-fold defaultstate="collapsed" desc="Generated Code">
		private void initComponents() {

			jLabel1 = new javax.swing.JLabel();
			jComboBox1 = new javax.swing.JComboBox();
			jLabel2 = new javax.swing.JLabel();
			comment = new javax.swing.JTextField();
			jScrollPane1 = new javax.swing.JScrollPane();
			taskTable = new TaskTable();
			cancel = new javax.swing.JButton();
			ok = new javax.swing.JButton();
			jLabel3 = new javax.swing.JLabel();
			reasonForEdit = new javax.swing.JTextField();
			jLabel4 = new javax.swing.JLabel();
			startTime = new javax.swing.JTextField();
			startAMPM = new javax.swing.JComboBox();
			jLabel5 = new javax.swing.JLabel();
			endTime = new javax.swing.JTextField();
			final Dimension timeSize = new Dimension(35, 20);
			endTime.setMinimumSize(timeSize);
			endTime.setPreferredSize(timeSize);
			startTime.setPreferredSize(timeSize);
			startTime.setMinimumSize(timeSize);
			endAMPM = new javax.swing.JComboBox();
			jLabel6 = new javax.swing.JLabel();
			date = new JDateChooser();

			setName("Form"); // NOI18N

			jLabel1.setText("Project"); // NOI18N
			jLabel1.setName("jLabel1"); // NOI18N

			jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(
					new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
			jComboBox1.setName("jComboBox1"); // NOI18N

			jLabel2.setText("Comment"); // NOI18N
			jLabel2.setName("jLabel2"); // NOI18N

			comment.setName("jTextField1"); // NOI18N

			jScrollPane1.setName("jScrollPane1"); // NOI18N

			taskTable.setModel(new javax.swing.table.DefaultTableModel(
					new Object[][] { { null, null, null, null },
							{ null, null, null, null },
							{ null, null, null, null },
							{ null, null, null, null } }, new String[] {
							"Title 1", "Title 2", "Title 3", "Title 4" }));
			taskTable.setName("jTable1"); // NOI18N
			jScrollPane1.setViewportView(taskTable);

			cancel.setText("Cancel"); // NOI18N
			cancel.setName("jButton1"); // NOI18N

			ok.setText("OK"); // NOI18N
			ok.setName("jButton2"); // NOI18N

			jLabel3.setText("Reason for edit"); // NOI18N
			jLabel3.setName("jLabel3"); // NOI18N

			reasonForEdit.setName("jTextField2"); // NOI18N

			jLabel4.setText("Start"); // NOI18N
			jLabel4.setName("jLabel4"); // NOI18N

			startTime.setName("jTextField3"); // NOI18N

			startAMPM.setModel(new javax.swing.DefaultComboBoxModel(
					new String[] { "AM", "PM" }));
			startAMPM.setName("jComboBox2"); // NOI18N

			jLabel5.setText("End"); // NOI18N
			jLabel5.setName("jLabel5"); // NOI18N

			endTime.setName("jTextField4"); // NOI18N

			endAMPM.setModel(new javax.swing.DefaultComboBoxModel(new String[] {
					"AM", "PM" }));
			endAMPM.setName("jComboBox3"); // NOI18N

			jLabel6.setText("Date"); // NOI18N
			jLabel6.setName("dateLbl"); // NOI18N

			date.setName("jTextField5"); // NOI18N

			final javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
					this);
			setLayout(layout);
			layout.setHorizontalGroup(layout
					.createParallelGroup(
							javax.swing.GroupLayout.Alignment.LEADING)
					.addGroup(
							javax.swing.GroupLayout.Alignment.TRAILING,
							layout.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.TRAILING)
													.addComponent(
															jScrollPane1,
															javax.swing.GroupLayout.Alignment.LEADING,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															613,
															Short.MAX_VALUE)
													.addGroup(
															layout.createSequentialGroup()
																	.addComponent(
																			ok)
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																	.addComponent(
																			cancel))
													.addGroup(
															javax.swing.GroupLayout.Alignment.LEADING,
															layout.createSequentialGroup()
																	.addGroup(
																			layout.createParallelGroup(
																					javax.swing.GroupLayout.Alignment.TRAILING,
																					false)
																					.addComponent(
																							jLabel3)
																					.addGroup(
																							layout.createSequentialGroup()
																									.addGroup(
																											layout.createParallelGroup(
																													javax.swing.GroupLayout.Alignment.LEADING)
																													.addGroup(
																															javax.swing.GroupLayout.Alignment.TRAILING,
																															layout.createSequentialGroup()
																																	.addComponent(
																																			jLabel1)
																																	.addPreferredGap(
																																			javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))
																													.addGroup(
																															layout.createSequentialGroup()
																																	.addComponent(
																																			jLabel6)
																																	.addGap(21,
																																			21,
																																			21)))
																									.addGroup(
																											layout.createParallelGroup(
																													javax.swing.GroupLayout.Alignment.LEADING,
																													false)
																													.addGroup(
																															javax.swing.GroupLayout.Alignment.TRAILING,
																															layout.createSequentialGroup()
																																	.addComponent(
																																			date,
																																			javax.swing.GroupLayout.PREFERRED_SIZE,
																																			123,
																																			javax.swing.GroupLayout.PREFERRED_SIZE)
																																	.addPreferredGap(
																																			javax.swing.LayoutStyle.ComponentPlacement.RELATED,
																																			javax.swing.GroupLayout.DEFAULT_SIZE,
																																			Short.MAX_VALUE)
																																	.addComponent(
																																			jLabel4))
																													.addGroup(
																															javax.swing.GroupLayout.Alignment.TRAILING,
																															layout.createSequentialGroup()
																																	.addComponent(
																																			jComboBox1,
																																			javax.swing.GroupLayout.PREFERRED_SIZE,
																																			209,
																																			javax.swing.GroupLayout.PREFERRED_SIZE)
																																	.addGap(18,
																																			18,
																																			18)
																																	.addComponent(
																																			jLabel2)))))
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																	.addGroup(
																			layout.createParallelGroup(
																					javax.swing.GroupLayout.Alignment.LEADING)
																					.addGroup(
																							layout.createSequentialGroup()
																									.addComponent(
																											startTime,
																											javax.swing.GroupLayout.PREFERRED_SIZE,
																											javax.swing.GroupLayout.DEFAULT_SIZE,
																											javax.swing.GroupLayout.PREFERRED_SIZE)
																									.addPreferredGap(
																											javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																									.addComponent(
																											startAMPM,
																											javax.swing.GroupLayout.PREFERRED_SIZE,
																											javax.swing.GroupLayout.DEFAULT_SIZE,
																											javax.swing.GroupLayout.PREFERRED_SIZE)
																									.addPreferredGap(
																											javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																									.addComponent(
																											jLabel5)
																									.addPreferredGap(
																											javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																									.addComponent(
																											endTime,
																											javax.swing.GroupLayout.PREFERRED_SIZE,
																											javax.swing.GroupLayout.DEFAULT_SIZE,
																											javax.swing.GroupLayout.PREFERRED_SIZE)
																									.addPreferredGap(
																											javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																									.addComponent(
																											endAMPM,
																											javax.swing.GroupLayout.PREFERRED_SIZE,
																											javax.swing.GroupLayout.DEFAULT_SIZE,
																											javax.swing.GroupLayout.PREFERRED_SIZE))
																					.addComponent(
																							reasonForEdit,
																							javax.swing.GroupLayout.DEFAULT_SIZE,
																							287,
																							Short.MAX_VALUE)
																					.addComponent(
																							comment,
																							javax.swing.GroupLayout.DEFAULT_SIZE,
																							287,
																							Short.MAX_VALUE))))
									.addContainerGap()));
			layout.setVerticalGroup(layout
					.createParallelGroup(
							javax.swing.GroupLayout.Alignment.LEADING)
					.addGroup(
							layout.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(jLabel1)
													.addComponent(
															jComboBox1,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE)
													.addComponent(jLabel2)
													.addComponent(
															comment,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addPreferredGap(
											javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(jLabel3)
													.addComponent(
															reasonForEdit,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addPreferredGap(
											javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(jLabel4)
													.addComponent(
															startTime,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE)
													.addComponent(
															startAMPM,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE)
													.addComponent(jLabel5)
													.addComponent(
															endTime,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE)
													.addComponent(
															endAMPM,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE)
													.addComponent(jLabel6)
													.addComponent(
															date,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addGap(18, 18, 18)
									.addComponent(
											jScrollPane1,
											javax.swing.GroupLayout.DEFAULT_SIZE,
											135, Short.MAX_VALUE)
									.addGap(18, 18, 18)
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(cancel)
													.addComponent(ok))
									.addContainerGap()));
		}// </editor-fold>
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 2012766326735632969L;

	private javax.swing.JButton cancel;

	private javax.swing.JTextField comment;
	private JDateChooser date;
	private final DateFormat dateAMPM = new SimpleDateFormat("a");
	private final DateFormat dateFormat = new SimpleDateFormat("hh:mm");
	private javax.swing.JComboBox endAMPM;
	private javax.swing.JTextField endTime;
	private javax.swing.JComboBox jComboBox1;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JLabel jLabel2;
	private javax.swing.JLabel jLabel3;
	private javax.swing.JLabel jLabel4;
	private javax.swing.JLabel jLabel5;
	private javax.swing.JLabel jLabel6;
	private javax.swing.JScrollPane jScrollPane1;
	private final ProjectService mProjectService;
	private javax.swing.JButton ok;
	private javax.swing.JTextField reasonForEdit;
	private javax.swing.JComboBox startAMPM;

	private javax.swing.JTextField startTime;
	private TaskTable taskTable;

	private final WorkService mWorkService;

	private Work mWork;

	private final DataDialog mParent;

	private final TaskProviderFactory mTaskProviderFactory;

	@Inject
	public TaskEditDialog(final ProjectService projectService,
			final WorkService workService, final DataDialog parent,
			final TaskProviderFactory taskProviderFactory,
			final TOLPropertiesDialog propertiesDialog) {
		mTolPropertiesDialog = propertiesDialog;
		mProjectService = projectService;
		mTaskProviderFactory = taskProviderFactory;
		mParent = parent;
		mWorkService = workService;
		setTitle("TRACT - Task Edit");
		final Image image = Toolkit.getDefaultToolkit().getImage(
				"stopwatch.PNG");
		setIconImage(image);
		add(new TaskEditPanel());
		cancel.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(final ActionEvent e) {
				TaskEditDialog.this.setVisible(false);
			}
		});

		ok.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(final ActionEvent e) {
				// loop through the rows of the table to identify tasks
				try {
					final TableModel model = taskTable.getModel();
					final UpdatedWork work = new UpdatedWork();
					work.setGUID(mWork.getGUID());
					for (int i = 0; i < model.getRowCount(); i++) {
						final Boolean required = (Boolean) model.getValueAt(i,
								1);
						final TaskLabel taskLabel = (TaskLabel) model
								.getValueAt(i, 2);
						if (taskLabel == null) {
							if (required) {
								throw new IllegalArgumentException(
										"A task for " + model.getValueAt(i, 0)
												+ " is required.");
							}
						} else {
							work.getTasks().add(taskLabel.getTask());
						}
					}
					final String reasonForEditStr = reasonForEdit.getText();
					if (reasonForEditStr.trim().length() == 0) {
						throw new IllegalArgumentException(
								"Reason for Edit must be provided.");
					}

					work.setComment(comment.getText());
					work.setProjectId(((ProjectLabel) jComboBox1
							.getSelectedItem()).getProject().getId());
					final GregorianCalendar cal = new GregorianCalendar();
					cal.setTime(date.getDate());
					work.setStart(getTime(startTime.getText(),
							(String) startAMPM.getSelectedItem(), cal));
					work.setEnd(getTime(endTime.getText(),
							(String) endAMPM.getSelectedItem(), cal));
					work.setReasonForEdit(reasonForEditStr);
					try {
						mWorkService.updateWork(work);
					} catch (final TractServiceException_Exception e1) {
						ErrorHandler.handleError(e1);
					}
					TaskEditDialog.this.setVisible(false);
					mParent.refresh();
				} catch (final IllegalArgumentException ex) {
					ErrorHandler.handleError(ex);
				}

			}
		});
		pack();
	}

	public void edit(final Work work) {
		mWork = work;
		comment.setText(work.getComment());
		final XMLGregorianCalendar start = work.getStart();
		if (start == null) {
			startTime.setText("");
			startAMPM.setSelectedItem("AM");
			date.setDate(new Date());
		} else {
			final Date startDate = start.toGregorianCalendar().getTime();
			date.setDate(startDate);
			startTime.setText(dateFormat.format(startDate));
			startAMPM.setSelectedItem(dateAMPM.format(startDate));
		}
		final XMLGregorianCalendar end = work.getEnd();
		if (end == null) {
			endTime.setText("");
			endAMPM.setSelectedItem("AM");
		} else {
			final Date endDate = end.toGregorianCalendar().getTime();
			endTime.setText(dateFormat.format(endDate));
			endAMPM.setSelectedItem(dateAMPM.format(endDate));
		}
		Project project = null;
		try {
			final ProjectList projectList = mProjectService.getAllProjects();
			final ProjectComboModel model = new ProjectComboModel(projectList);
			jComboBox1.setModel(model);

			for (final Project p : projectList.getProject()) {
				if (p.getId() == work.getProjectId()) {
					project = p;
				}
			}
			jComboBox1.setSelectedItem(model.new ProjectLabel(project));
		} catch (final TractServiceException_Exception e) {
			ErrorHandler.handleError(e);
		}
		populateTaskForm(project, work);
		System.out.println(startTime.getSize());
		setVisible(true);
	}

	private XMLGregorianCalendar getTime(final String time, final String amPM,
			final GregorianCalendar date) {
		XMLGregorianCalendar xcal = null;
		if ((time != null) && (time.trim().length() > 1)) {
			try {
				xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(
						date);
				final Scanner scanner = new Scanner(time);
				scanner.useDelimiter(":");
				int hour = scanner.nextInt();
				final int minute = scanner.nextInt();
				if ("PM".equals(amPM) && (hour < 12)) {
					hour += 12;
				} else if ("AM".equals(amPM) && (hour == 12)) {
					hour = 0;
				}
				xcal.setHour(hour);
				xcal.setMinute(minute);
			} catch (final DatatypeConfigurationException e) {
				ErrorHandler.handleError(e);
			}
		}
		return xcal;
	}

	private void populateTaskForm(final Project project, final Work work) {
		try {
			final List<WorkStore> workStores = mProjectService
					.getProjectStores(project.getId()).getWorkStore();
			final int size = workStores.size();
			final Object[][] data = new Object[size][3];
			for (int i = 0; i < size; i++) {
				data[i][0] = workStores.get(i).getLabel();
				data[i][1] = workStores.get(i).isRequired();
				data[i][2] = null;
			}
			taskTable.setModel(new javax.swing.table.DefaultTableModel(data,
					new String[] { "Work Store", "Required", "Task" }));
			final Map<Long, Task> taskMap = new HashMap<Long, Task>();
			if (work != null) {
				for (final Task t : work.getTasks()) {
					taskMap.put(t.getStoreId(), t);
				}
			}
			for (int i = 0; i < size; i++) {
				final WorkStore store = workStores.get(i);
				final TaskProvider taskProvider = mTaskProviderFactory
						.getTaskProvider(store);
				final MyComboBoxRenderer taskRenderer = new MyComboBoxRenderer();
				final TaskComboModel taskModel = new TaskComboModel(
						taskProvider.getTasks());
				if (taskMap.containsKey(store.getId())) {
					final TaskLabel taskLabel = taskModel.new TaskLabel(
							taskMap.get(store.getId()));
					taskTable.setValueAt(taskLabel, i, 2);
				}
				taskRenderer.setModel(taskModel);
				final DefaultCellEditor cellEditor = new DefaultCellEditor(
						taskRenderer);
				taskTable.setTaskEditor(i, cellEditor);
				taskTable.setTaskRenderer(i, taskRenderer);

			}
			taskTable.addMouseListener(new TaskPropertiesMouseAdapter(
					mTolPropertiesDialog, taskTable));
			final TableColumn column = taskTable.getColumnModel().getColumn(1);
			column.setCellRenderer(new MyCheckBoxRenderer());

		} catch (final TractServiceException_Exception e) {
			ErrorHandler.handleError(e);
		}
	}
}